package com.littleken.foodieCommon.configuration;

import com.littleken.foodieCommon.Response.ErrorCode;
import com.littleken.foodieCommon.Response.ServerResponse;
import com.littleken.foodieCommon.exception.GoffException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;

import java.util.List;

/*
 * 错误统一处理逻辑
 * Create by littleken on 2020/11/23 15:22
 */
@ControllerAdvice
public class ExceptionHandlerController {

    private static final Logger logger = LoggerFactory.getLogger(ExceptionHandlerController.class);

    @ExceptionHandler(value = {Exception.class})
    public ResponseEntity<ServerResponse<Object>> handleException(final Exception ex, final WebRequest req) {
        logger.error("{}", ex);
        if (ex instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException validException = (MethodArgumentNotValidException) ex;
            BindingResult result = validException.getBindingResult();
            String errorInfo = getValidatedErrorsMsg(result);
            return new ResponseEntity<>(
                    ServerResponse.fail(ErrorCode.PARAMS_INVALID.getCode(), errorInfo), HttpStatus.BAD_REQUEST);
        } else if (ex instanceof org.springframework.http.converter.HttpMessageNotReadableException) {
            //捕捉前端json格式错误
            return new ResponseEntity<>(new ServerResponse<>(ErrorCode.JSON_FORMAT_ERR.getCode(),
                    ErrorCode.JSON_FORMAT_ERR.getDscr()), HttpStatus.BAD_REQUEST);
        } else if (ex instanceof org.springframework.web.bind.MissingServletRequestParameterException) {
            return new ResponseEntity<>(new ServerResponse<>(ErrorCode.PARAMS_INVALID.getCode(),
                    String.format("%s参数,类型%s缺失",
                            ((org.springframework.web.bind.MissingServletRequestParameterException) ex)
                                    .getParameterName(),
                            ((org.springframework.web.bind.MissingServletRequestParameterException) ex)
                                    .getParameterType())), HttpStatus.BAD_REQUEST);
        } else if (ex instanceof GoffException) {
            //捕捉系统运行时候产生的错误
            return new ResponseEntity<>(
                    new ServerResponse<>(((GoffException) ex).getErrcode(), ((GoffException) ex).getErrmsg(),
                            ((GoffException) ex).getDetailErrMsg()), HttpStatus.OK);
        }
        //剩下没有捕捉的错误
        return new ResponseEntity<>(ServerResponse.fail(ErrorCode.INTERNAL_ERR, ex.getMessage()),
                HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * 获取拼接好的验证错误信息
     */
    private String getValidatedErrorsMsg(BindingResult bindingResult) {
        StringBuilder msg = new StringBuilder();
        List<ObjectError> errors = bindingResult.getAllErrors();
        for (ObjectError error : errors) {
            FieldError fieldError = (FieldError) error;
            msg.append(fieldError.getObjectName()).append("_")
                    .append(fieldError.getField()).append(",")
                    .append(fieldError.getDefaultMessage())
                    .append(";");
        }
        return msg.toString();
    }
}
